package com.jiangnanxiaoguan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.jiangnanxiaoguan.common.BaseContext;
import com.jiangnanxiaoguan.entity.*;
import com.jiangnanxiaoguan.mapper.OrdersMapper;
import com.jiangnanxiaoguan.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author 不愿透露姓名的狂热者
 * @since 2022-09-11
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private UserService userService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private OrderDetailService orderDetailService;


    @Transactional
    @Override
    public void submit(Orders orders) {
        Long userId = BaseContext.getCurrentId();

        // 1.查询购物车表条件
        LambdaQueryWrapper<ShoppingCart> shoppingCartLambdaQueryWrapper = new LambdaQueryWrapper<>();
        shoppingCartLambdaQueryWrapper.eq(ShoppingCart::getUserId, userId);
        // 2.查询购物车表
        List<ShoppingCart> shoppingCartList = shoppingCartService.list(shoppingCartLambdaQueryWrapper);

        // 3.查询用户表
        User user = userService.getById(userId);

        // 查询地址表
        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());


        // 4.1（MP提供）生成一个雪花id，给订单表主键和订单号字段使用，主要是订单号MP无法自动生成雪花id。
        long orderId = IdWorker.getId();

        // 4.2 原子类，保证订单总金额计算结果精确，不受线程安全影响。（使用普通的int或Integer计算其实也行）
        // （实际上在这没啥用，因为每个用户都是不同设备、不同请求和不同线程，哪来的线程安全问题）
        AtomicInteger atomicInteger = new AtomicInteger(0);

        // 4.先封装订单明细（map或增强for），因为要使用购物车表数据，顺便能将订单表的总金额计算出来。
        List<OrderDetail> orderDetailList = shoppingCartList.stream().map(shoppingCart -> {
            OrderDetail orderDetail = new OrderDetail();
            // 封装订单明细数据（一个个封装，或直接拷贝（因为订单明细的字段在购物车表中都有，而且字段名一样））
//            orderDetail.setName(shoppingCart.getName());
//            orderDetail.setImage(shoppingCart.getImage());
//            orderDetail.setOrderId(orderId);
//            orderDetail.setDishId(shoppingCart.getDishId());
//            orderDetail.setSetmealId(shoppingCart.getSetmealId());
//            orderDetail.setDishFlavor(shoppingCart.getDishFlavor());
//            orderDetail.setNumber(shoppingCart.getNumber());
//            orderDetail.setAmount(shoppingCart.getAmount());
            BeanUtils.copyProperties(shoppingCart, orderDetail);
            // 订单id在购物车表中没有
            orderDetail.setOrderId(orderId);

            // 顺便计算总金额，给订单表使用
            Integer number = shoppingCart.getNumber();
            BigDecimal amount = shoppingCart.getAmount();
            // 总金额
            BigDecimal multiplyResult = amount.multiply(new BigDecimal(number));
            atomicInteger.addAndGet(multiplyResult.intValue());

            return orderDetail;
        }).collect(Collectors.toList());

        // 5.封装订单表数据
        orders.setId(orderId); // 这里简单一点，为了和订单号保持一致。
        orders.setNumber(String.valueOf(orderId)); // 正常来说订单号是单独生成的，但这个项目并没有支付功能，简化一下。
        orders.setStatus(2); // 待派送，写死的数据。
        orders.setUserId(userId);
//        orders.setAddressBookId(orders.getAddressBookId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
//        orders.setPayMethod(orders.getPayMethod());
        orders.setAmount(new BigDecimal(atomicInteger.intValue()));
//        orders.setRemark(orders.getRemark());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
                            + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
                            + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
                            + addressBook.getDetail());
        orders.setUserName(user.getName());
        orders.setConsignee(addressBook.getConsignee());

        // 6.保存订单数据
        save(orders);

        // 7.保存订单明细数据（批量操作）
        orderDetailService.saveBatch(orderDetailList);

        // 8.根据用户id删除购物车数据
        shoppingCartService.remove(shoppingCartLambdaQueryWrapper);
    }
}
